using System;
using System.Web;
using System.Net;
using System.IO;
using System.Text;
using System.Collections.Generic;

namespace Utils
{
public class ServiceUtil
{
	public static void log(string msg)
	{
		string path = System.Web.HttpContext.Current.Server.MapPath("./logs/");
		if(!Directory.Exists(path))
		{
			Directory.CreateDirectory(path);
		}
		StreamWriter sw = File.AppendText(path + DateTime.Now.ToString("yyyyMMdd") + ".log");
		sw.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")+","+msg);
		sw.Close();
	}

	public static string getToken(string username, string password)
	{
		string url = "http://localhost:8080/auth/realms/demo/tokens/grants/access";
		string postString = string.Format("username="+username+"&password="+password+"&client_id=admin-client&grant_type=password");

		return NetUtil.post(url, postString, null);
	}

	public static string getAccessToken()
	{
		string json = getToken("admin", "password");

		Dictionary<string,string> tokens = JsonUtil.jsonParse(json);

		string token = tokens["access_token"];

		return token;
	}

	public static string getUserAccessToken(string username, string password)
	{
		string json = getToken(username, password);

		Dictionary<string,string> tokens = JsonUtil.jsonParse(json);

		string token = tokens["access_token"];

		return token;
	}

	public static string getRealmInfo(string realm, string token)
	{
		return NetUtil.get("http://localhost:8080/auth/admin/realms/" + realm, token);
	}

	public static string getUsersJson(string token)
	{
		string url = "http://localhost:8080/auth/admin/realms/demo/users";

		return NetUtil.get(url, token);
	}

	public static string addUser(string token, string username, string password)
	{
		string URLAuth = "http://localhost:8080/auth/admin/realms/demo/users";
		//,\"clientRoles\":{\"account\":[\"manage-account\"]}
		//,\"credentials\":[{\"type\":\"password\",\"value\":\""+password+"\"}]
		string postString = "{\"username\":\""+username+"\",\"enabled\":true,\"email\":\""+username+"@test.com\"}";

		const string contentType = "application/json";
		System.Net.ServicePointManager.Expect100Continue = false;

		CookieContainer cookies = new CookieContainer();
		HttpWebRequest webRequest = WebRequest.Create(URLAuth) as HttpWebRequest;
		webRequest.Method = "POST";
		webRequest.ContentType = contentType;
		webRequest.CookieContainer = cookies;
		webRequest.ContentLength = postString.Length;

		webRequest.Headers["Authorization"] = "Bearer " + token;

		StreamWriter requestWriter = new StreamWriter(webRequest.GetRequestStream());
		requestWriter.Write(postString);
		requestWriter.Close();

		string responseData = "";

		try
		{
			using (WebResponse response = webRequest.GetResponse())
			{
				StreamReader responseReader = new StreamReader(response.GetResponseStream());
				responseData = responseReader.ReadToEnd();
				responseReader.Close();
			}
		}
		catch (WebException e)
		{
			string msg = "";
			using (WebResponse response = e.Response)
			{
				HttpWebResponse httpResponse = (HttpWebResponse) response;
				msg = string.Format("Error code: {0}; ", httpResponse.StatusCode);
				using (Stream data = response.GetResponseStream())
				{
					using (StreamReader reader = new StreamReader(data))
					{
						msg += reader.ReadToEnd();
					}
				}
			}
			throw new Exception(msg);
		}

		return responseData;
	}

	public static string updateUser(string token, string userid, string username, string roleid, string rolename)
	{
		string URLAuth = "http://localhost:8080/auth/admin/realms/demo/users/"+userid;

		string postString = "{\"id\":\""+userid+"\",\"username\":\""+username+"\",\"enabled\":true,\"realmRoles\":[\"user\"],\"clientRoles\":{\"account\":[\"manage-account\"]}}";

		const string contentType = "application/json";
		System.Net.ServicePointManager.Expect100Continue = false;

		CookieContainer cookies = new CookieContainer();
		HttpWebRequest webRequest = WebRequest.Create(URLAuth) as HttpWebRequest;
		webRequest.Method = "POST";
		webRequest.ContentType = contentType;
		webRequest.CookieContainer = cookies;
		webRequest.ContentLength = postString.Length;

		webRequest.Headers["Authorization"] = "Bearer " + token;

		StreamWriter requestWriter = new StreamWriter(webRequest.GetRequestStream());
		requestWriter.Write(postString);
		requestWriter.Close();

		string responseData = "";

		try
		{
			using (WebResponse response = webRequest.GetResponse())
			{
				StreamReader responseReader = new StreamReader(response.GetResponseStream());
				responseData = responseReader.ReadToEnd();
				responseReader.Close();
			}
		}
		catch (WebException e)
		{
			string msg = "";
			using (WebResponse response = e.Response)
			{
				HttpWebResponse httpResponse = (HttpWebResponse) response;
				msg = string.Format("Error code: {0}; ", httpResponse.StatusCode);
				using (Stream data = response.GetResponseStream())
				{
					using (StreamReader reader = new StreamReader(data))
					{
						msg += reader.ReadToEnd();
					}
				}
			}
			throw new Exception(msg);
		}

		return responseData;
	}

	public static string findUserId(string token, string username)
	{
		string URLAuth = "http://localhost:8080/auth/admin/realms/demo/users/"+username;

		CookieContainer cookies = new CookieContainer();
		HttpWebRequest webRequest = WebRequest.Create(URLAuth) as HttpWebRequest;
		webRequest.Headers["Authorization"] = "Bearer " + token;
		webRequest.CookieContainer = cookies;

		string responseData = "";

		try
		{
			using (WebResponse response = webRequest.GetResponse())
			{
				StreamReader responseReader = new StreamReader(response.GetResponseStream());
				responseData = responseReader.ReadToEnd();
				responseReader.Close();
			}
		}
		catch (WebException e)
		{
			string msg = "";
			using (WebResponse response = e.Response)
			{
				HttpWebResponse httpResponse = (HttpWebResponse) response;
				msg = string.Format("Error in findUserId, code: {0}, {1}; ", (int)httpResponse.StatusCode, httpResponse.StatusCode);
				using (Stream data = response.GetResponseStream())
				{
					using (StreamReader reader = new StreamReader(data))
					{
						msg += reader.ReadToEnd();
					}
				}
			}
			throw new Exception(msg);
		}

		int i = 0, i2 = 0, i3 = 0;
		if((i=responseData.IndexOf("id", i+1)) > 0)
		{
			i2 = responseData.IndexOf(":",i);
			i3 = responseData.IndexOf(",",i);
			return responseData.Substring(i2, i3 - i2).Trim(" \":".ToCharArray());
		}

		return "";
	}

	public static string resetUserPassword(string token, string userid, string password)
	{
		string URLAuth = "http://localhost:8080/auth/admin/realms/demo/users/"+userid+"/reset-password";
		string postString = "{\"type\":\"password\",\"value\":\""+password+"\"}";

		const string contentType = "application/json";
		System.Net.ServicePointManager.Expect100Continue = false;

		CookieContainer cookies = new CookieContainer();
		HttpWebRequest webRequest = WebRequest.Create(URLAuth) as HttpWebRequest;
		webRequest.Method = "PUT";
		webRequest.ContentType = contentType;
		webRequest.CookieContainer = cookies;
		webRequest.ContentLength = postString.Length;

		webRequest.Headers["Authorization"] = "Bearer " + token;

		StreamWriter requestWriter = new StreamWriter(webRequest.GetRequestStream());
		requestWriter.Write(postString);
		requestWriter.Close();

		string responseData = "";

		try
		{
			using (WebResponse response = webRequest.GetResponse())
			{
				StreamReader responseReader = new StreamReader(response.GetResponseStream());
				responseData = responseReader.ReadToEnd();
				responseReader.Close();
			}
		}
		catch (WebException e)
		{
			string msg = "";
			using (WebResponse response = e.Response)
			{
				HttpWebResponse httpResponse = (HttpWebResponse) response;
				msg = string.Format("Error in resetUserPassword, code: {0}; ", httpResponse.StatusCode);
				using (Stream data = response.GetResponseStream())
				{
					using (StreamReader reader = new StreamReader(data))
					{
						msg += reader.ReadToEnd();
					}
				}
			}
			throw new Exception(msg);
		}

		return responseData;
	}

	public static string getUserRoles(string token, string userId)
	{
		string URLAuth = "http://localhost:8080/auth/admin/realms/demo/users/"+userId+"/role-mappings/realm";

		CookieContainer cookies = new CookieContainer();
		HttpWebRequest webRequest = WebRequest.Create(URLAuth) as HttpWebRequest;
		webRequest.Headers["Authorization"] = "Bearer " + token;
		webRequest.CookieContainer = cookies;

		string responseData = "";

		try
		{
			using (WebResponse response = webRequest.GetResponse())
			{
				StreamReader responseReader = new StreamReader(response.GetResponseStream());
				responseData = responseReader.ReadToEnd();
				responseReader.Close();
			}
		}
		catch (WebException e)
		{
			string msg = "";
			using (WebResponse response = e.Response)
			{
				HttpWebResponse httpResponse = (HttpWebResponse) response;
				msg = string.Format("Error code: {0}, {1}; ", (int)httpResponse.StatusCode, httpResponse.StatusCode);
				using (Stream data = response.GetResponseStream())
				{
					using (StreamReader reader = new StreamReader(data))
					{
						msg += reader.ReadToEnd();
					}
				}
			}
			throw new Exception(msg);
		}

		return responseData;
	}

	public static string setUserRoles(string token, string userId, string roleId, string roleName)
	{
		string URLAuth = "http://localhost:8080/auth/admin/realms/demo/users/"+userId+"/role-mappings/realm";
		string postString = "[{\"id\":\""+roleId+"\",\"name\":\""+roleName+"\"}]";

		const string contentType = "application/json";
		System.Net.ServicePointManager.Expect100Continue = false;

		CookieContainer cookies = new CookieContainer();
		HttpWebRequest webRequest = WebRequest.Create(URLAuth) as HttpWebRequest;
		webRequest.Method = "POST";
		webRequest.ContentType = contentType;
		webRequest.CookieContainer = cookies;
		webRequest.ContentLength = postString.Length;

		webRequest.Headers["Authorization"] = "Bearer " + token;

		StreamWriter requestWriter = new StreamWriter(webRequest.GetRequestStream());
		requestWriter.Write(postString);
		requestWriter.Close();

		string responseData = "";

		try
		{
			using (WebResponse response = webRequest.GetResponse())
			{
				StreamReader responseReader = new StreamReader(response.GetResponseStream());
				responseData = responseReader.ReadToEnd();
				responseReader.Close();
			}
		}
		catch (WebException e)
		{
			string msg = "";
			using (WebResponse response = e.Response)
			{
				HttpWebResponse httpResponse = (HttpWebResponse) response;
				msg = string.Format("Error in setUserRoles, code: {0}; ", httpResponse.StatusCode);
				using (Stream data = response.GetResponseStream())
				{
					using (StreamReader reader = new StreamReader(data))
					{
						msg += reader.ReadToEnd();
					}
				}
			}
			throw new Exception(msg);
		}

		return responseData;
	}

	public static string findRoleId(string token, string rolename)
	{
		string URLAuth = "http://localhost:8080/auth/admin/realms/demo/roles/"+rolename;

		CookieContainer cookies = new CookieContainer();
		HttpWebRequest webRequest = WebRequest.Create(URLAuth) as HttpWebRequest;
		webRequest.Headers["Authorization"] = "Bearer " + token;
		webRequest.CookieContainer = cookies;

		string responseData = "";

		try
		{
			using (WebResponse response = webRequest.GetResponse())
			{
				StreamReader responseReader = new StreamReader(response.GetResponseStream());
				responseData = responseReader.ReadToEnd();
				responseReader.Close();
			}
		}
		catch (WebException e)
		{
			string msg = "";
			using (WebResponse response = e.Response)
			{
				HttpWebResponse httpResponse = (HttpWebResponse) response;
				msg = string.Format("Error in findRoleId, code: {0}, {1}; ", (int)httpResponse.StatusCode, httpResponse.StatusCode);
				using (Stream data = response.GetResponseStream())
				{
					using (StreamReader reader = new StreamReader(data))
					{
						msg += reader.ReadToEnd();
					}
				}
			}
			throw new Exception(msg);
		}

		int i = 0, i2 = 0, i3 = 0;
		if((i=responseData.IndexOf("id", i+1)) > 0)
		{
			i2 = responseData.IndexOf(":",i);
			i3 = responseData.IndexOf(",",i);
			return responseData.Substring(i2, i3 - i2).Trim(" \":".ToCharArray());
		}

		return "";
	}
}
}